using System.Collections;
using System.Collections.Generic;
using MyFrame.Pool;
using Platform.Skill.Core;
using GardeningSkeleton.Platform.SkillSpace;
using UnityEngine;
using Platform.CharacterData;
using Plugin.Tool;
using System.Linq;

namespace Platform.Skill.Deployer
{
    /// <summary>
    /// 技能释放器
    /// </summary>
    public class SkillDeployer : MonoBehaviour
    {
        [HideInInspector] public SpriteRenderer sr;
        [HideInInspector] public Animator anim;
        [HideInInspector] public Rigidbody2D rb;

        protected SkillData skillData;
        public SkillData SkillData //技能管理器提供
        {
            get { return skillData; }
            set { skillData = value; InitDeplopyer(); }
        }
        //范围选择算法
        private ISkillSelector selector;
        //效果算法对象 
        private BaseImpactEffect[] impactArray;

        /// <summary>
        /// 初始化释放器  在设置技能时调用
        /// </summary>
        private void InitDeplopyer()//初始化释放器 
        {
            //范围选择
            selector = DeployerConfigFactory.CreateSkillSelector(skillData);
            //效果
            impactArray = DeployerConfigFactory.CreateImpactEffects(skillData);
        }
        //范围选择
        public void chooseTargets()
        {
            if (selector != null) skillData.attackTargets = selector?.SelectTarget(skillData, this.transform);
        }
        /// <summary>
        /// 执行所有效果, 自动赋值常用变量
        /// </summary>
        public void ImpactTargets()
        {
            for (int i = 0; i < impactArray.Length; i++)
            {
                impactArray[i].skillData = SkillData;
                impactArray[i].Execute(this);
            }
        }

        /// <summary>
        /// 结束效果， 实际是传递给所有效果
        /// </summary>
        public virtual void EndEffect()
        {
            for (int i = 0; i < impactArray.Length; i++)
            {
                impactArray[i].EndEffect();
            }
        }

        //供技能管理器调用，由子类实现，定义具体释放策略
        public virtual void DeploySkill()
        {
            //范围选择
            chooseTargets();
            //执行影响算法
            ImpactTargets();
        }

        #region  检测范围绘制
        public float rangeTemp;
        protected virtual void OnDrawGizmos()
        {
            // 绘制圆形
            Gizmos.color = Color.red; // 设置圆形颜色
            Gizmos.DrawWireSphere(transform.position, rangeTemp); // 绘制半径为 data.range 的圆形
        }

        #endregion

        #region  物理碰撞
        protected virtual void OnTriggerEnter2D(Collider2D other)
        {
            for (int i = 0; i < impactArray.Length; i++)
            {
                impactArray[i].OnImpactTriggerEntry(other);
            }
        }

        protected virtual void OnTriggerExit2D(Collider2D other)
        {
            for (int i = 0; i < impactArray.Length; i++)
            {
                impactArray[i].OnImpactTriggerExit(other);
            }
        }

        #endregion

        #region  触发伤害
        private bool isAttack = false;
        // 伤害的触发时机差异很大，不适合作为效果
        public virtual void AttackStart()
        {
            switch (skillData.disappearType)
            {
                case CalculDamageType.Once:
                    Attack();
                    break;
                case CalculDamageType.Continue:
                    if (isAttack) return;
                    isAttack = true;
                    ZTimer.SetInterval(skillData.attackInterval, Attack);
                    break;
            }
        }
        /// <summary>
        /// 敌人选取两种形式： 碰撞 、 射线检测
        /// </summary>
        /// <param name="other"></param>
        public virtual void AttackStart(Collider2D other)
        {
            AttackStart(other.transform);
        }
        public virtual void AttackStart(Transform other)
        {
            if (Tool.IsInLayerMask(other.gameObject, skillData.attackTargetLayers))
            {
                //这里区分单体攻击
                if (skillData.attackType == SkillAttackType.single)
                {
                    skillData.attackTargets.Clear();
                }
                skillData.attackTargets.Add(other);
            }
            AttackStart();
        }
        public virtual void AttackEnd()
        {
            isAttack = false;
            ZTimer.ClearTimer(Attack);
        }
        private void Attack()
        {
            if (skillData.attackTargets?.Count > 0)
            {
                foreach (var entity in skillData.attackTargets.ToArray())
                {
                    var enemyEntity = entity.GetComponent<Enemy>();
                    if (enemyEntity != null) enemyEntity.FreezeTimeFor(skillData.freezeTime);

                    switch (skillData.damageType)
                    {
                        case DamageType.Normal:
                        case DamageType.Magic:
                            entity.GetComponent<CharacterStats>().BeDamage(OwnerEntity.stats, skillData.attackDamage, skillData.damageType);
                            break;
                        case DamageType.OwnerAttack:
                            //使用原始攻击力
                            entity.GetComponent<CharacterStats>().BeDamage(OwnerEntity.stats);
                            break;
                        case DamageType.OwnerMagic:
                            //使用原始魔法攻击+技能攻击
                            entity.GetComponent<CharacterStats>().BeMagicalDamage(OwnerEntity.stats, skillData.attackDamage);
                            break;
                    }
                }
            }
        }

        #endregion


        #region 简写
        public Entity OwnerEntity => skillData.owner.GetComponent<Entity>();
        public Vector3 OwnerPos => skillData.owner.transform.position;
        public float OwnerDamage => OwnerEntity.stats.damage.Value;

        public void Release()
        {
            PoolMgr.Instance.Release(this.gameObject);
        }


        #endregion
    }
}